package com.juku2024.juku.analysis

import android.content.Context
import com.juku2024.juku.analysis.source.CommonHttpParse
import com.juku2024.juku.R
import com.juku2024.juku.analysis.source.FlvcdHttpParse
import com.juku2024.juku.analysis.source.WebParse
import com.juku2024.juku.db.NoteRoomUtils
import com.juku2024.juku.dialog.DialogUtils
import com.juku2024.juku.tools.*

object AnalysisVideoTools {

    /**
     * 解析地址缓存池，
     * 解析方案：
     *  同时加载2个付费http解析和一个web解析
     *  谁解析快，谁先返回，当做此次解析源，其他的备用
     *  所有解析到的视频源都放到 parsePathList 中，如果播放出错，那么就尝试将 parsePathList 对应的url删除，使用下一个源开始播放
     *  每次调用 getVideoUrl 都会清空 parsePathList
     *
     *  0: 通用解析方式
     *  1：ParseVideo平台解析
     *  4：WebView解析
     *
     */
    private val parsePathList by lazy { ArrayList<ParseItem>() }
    private val httpParseList by lazy { ArrayList<BaseHttpParse>() }
    var isUserParse = false
    @Volatile private  var parseSourceSize: Int = 0
    // 这个大小是不会变的
    private var totalParseCount = 0

    fun getVideoUrl(context: Context, sourceId: Int, videoId: String?, videoName: String?, title: String?, callback: OnParseVideoListener) {
        // 重置内容
        reset()
        val homeModel = NoteRoomUtils.getInstance().homeTabDao().query()
        val sourceModel = homeModel?.analysis?.firstOrNull { it.sourceId == sourceId }
        if (sourceModel?.analysisUrl.isNullOrEmpty() || videoId == null) {
            LogC.e("parse -> 无需解析，直接返回...")
            isUserParse = false
            VideoAnalysisUtils.isUseParse(false)
            callback.onSuccess("", videoId)
            return
        }
        VideoAnalysisUtils.isUseParse(true)

        isUserParse = true
        // 所有http和web解析同时进行
        // 所有解析源个数
        parseSourceSize = sourceModel?.analysisUrl?.size ?: 0
        totalParseCount = parseSourceSize
        // 反馈在一个callback，便于统计
        val listener = object : OnParseVideoListener {
            override fun onSuccess(sourceName: String?, url: String?, headerMap: Map<String, String>?) {
                LogC.e("parse -> ${sourceName}解析成功..." + url)
                val parseItem = ParseItem()
                parseItem.source = sourceName
                parseItem.url = url
                parseItem.title = "$videoName $title"
                parseItem.headerMap = headerMap
                // 加入缓存集合
                parsePathList.add(parseItem)
                // 谁最先解析成功，
                if (parsePathList.size <= 1) {
                    LogC.e("parse -> $sourceName -> 最先解析成功，直接返回前端播放...")
                    var header: HashMap<String, String>? = null
                    if (sourceId == 4) { // 芒果
                        header = HashMap()
                        header["user-agent"] = " Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
                    }
                    callback.onSuccess(sourceName, url, header)
                    if (parseSourceSize < totalParseCount) { // 此时使用的是备用源
                        // 使用备用源次数 +1
                        VideoAnalysisUtils.autoChangeParseSource()
                    }
                } else {
                    LogC.e("parse -> 备用源解析成功，直接加入缓存列表...$url")
                }
            }

            override fun onFail(sourceName: String?) {
                // 统计失败
                // 统计失败
                VideoAnalysisUtils.parseError(videoName, sourceName, title)
                // 出错，解析源个数要-1
                parseSourceSize -= 1
                if (parseSourceSize == parsePathList.size) { // 所有解析都完成了
                    LogC.e("parse -> 所有解析都执行完成...")
                    if (parsePathList.isEmpty()) {
                        LogC.e("parse -> 没有可用的源，反馈前端失败...")
                        callback.onFail(sourceName)
                    }
                } else {
                    LogC.e("parse -> 等待其他源解析，看是否有成功解析...")
                }
            }
        }
        // 同时执行所有的请求
        sourceModel?.analysisUrl?.forEach { source ->

            when (source.id) {
                3 -> {
                    val httpParse = FlvcdHttpParse()
                    httpParse.parseVideo(context, videoId, source, listener)
                    httpParseList.add(httpParse)
                }

                4 -> {
                    val httpParse = WebParse()
                    httpParse.parseVideo(context, videoId, source, listener)
                    httpParseList.add(httpParse)
                }
                else -> {
                    val httpParse = CommonHttpParse()
                    httpParse.parseVideo(context, videoId, source, listener)
                    httpParseList.add(httpParse)
                }
            }
        }
        // 请求使用解析的次数，对应所有源失败
        AnalysisUtils.analysis(AnalysisConstants.EVENT_SOURCE, AnalysisConstants.KEY_SOURCE_REQUEST_TIME, 1)
    }

    private fun reset(){
        parseSourceSize = 0
        parsePathList.clear()
        httpParseList.forEach {
            it.release()
        }
        httpParseList.clear()
    }


    fun release() {
        parseSourceSize = 0
        parsePathList.clear()
        httpParseList.forEach {
            it.release()
        }
        httpParseList.clear()
    }

    /**
     *  是否还有可用解析源 出了当前使用的，还要有一个可以用来缓存用的
     */
    fun hasUsefulUrl(): Boolean{
        return parseSourceSize > 0
    }

    fun removeUselessSource(){
        if (parsePathList.isEmpty() || parseSourceSize == 0) return
        parsePathList.removeFirst()
        parseSourceSize -= 1
    }

    fun getCurrentParseSource(): String? {
        return if (parsePathList.isEmpty()) {
            null
        } else {
            parsePathList.firstOrNull()?.source
        }
    }

    fun getCacheParseContent(): ParseItem? {
        return if (parsePathList.isNullOrEmpty()) {
            null
        } else {
            // 此时第一个源就是要用的
            parsePathList.firstOrNull()
        }

    }

    private var isShowSSLDialog = false
    fun showSSLDialog(context: Context?){
        if (!isShowSSLDialog) {
            val activity = AppUtils.findActivity(context)?:return
            DialogUtils.showAlertDialog(activity, "网站SSL警告","视频地址ssl证书验证失败",
                AppUtils.getString(R.string.confirm),{
                httpParseList.forEach {
                    it.proceed()
                }
                isShowSSLDialog = false

            }, AppUtils.getString(R.string.cancel),{
                httpParseList.forEach {
                    it.cancel()
                }
                isShowSSLDialog = false
            })
            isShowSSLDialog = true
        }
    }

    class ParseItem{
        var url: String? = null
        var title: String? = null
        var source: String? = null
        var headerMap: Map<String, String>? = null
    }
}